package com.ilop.sthome.mvp.present.device;

import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.util.Log;

import com.aliyun.iot.aep.sdk.apiclient.callback.IoTResponse;
import com.example.common.mvp.BasePresenterImpl;
import com.example.common.utils.LiveDataBus;
import com.ilop.sthome.common.CommonId;
import com.ilop.sthome.common.command.SendDeviceCommand;
import com.ilop.sthome.common.command.SendSceneCommand;
import com.ilop.sthome.common.udp.GatewayUdpUtil;
import com.ilop.sthome.data.bean.VirtualUserBean;
import com.ilop.sthome.data.enums.NetworkType;
import com.ilop.sthome.data.enums.SmartDevice;
import com.ilop.sthome.data.greenDao.DeviceInfoBean;
import com.ilop.sthome.mvp.contract.device.DeviceContract;
import com.ilop.sthome.mvp.model.CommonModel;
import com.ilop.sthome.mvp.model.common.CommonModelImpl;
import com.example.common.mvp.onModelCallBack;
import com.ilop.sthome.ui.activity.detail.AlarmDeviceActivity;
import com.ilop.sthome.ui.activity.detail.lock.LockDetailActivity;
import com.ilop.sthome.ui.activity.detail.OutDoorDetailActivity;
import com.ilop.sthome.ui.activity.detail.socket.SocketDetailActivity;
import com.ilop.sthome.ui.activity.detail.THCheckDetailActivity;
import com.ilop.sthome.ui.activity.detail.thermostat.TempControlDetailActivity;
import com.example.xmpic.ui.activity.CameraDeviceActivity;
import com.ilop.sthome.utils.CoderUtils;
import com.ilop.sthome.utils.ParsingJsonUtil;
import com.ilop.sthome.utils.greenDao.utils.DeviceDaoUtil;
import com.ilop.sthome.utils.greenDao.utils.RoomDaoUtil;
import com.ilop.sthome.utils.greenDao.utils.SceneDaoUtil;
import com.ilop.sthome.utils.system.NetWorkUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author skygge
 * @date 2019-10-10.
 * GitHub：javofxu@github.com
 * email：skygge@yeah.net
 * description：设备页业务逻辑
 */
public class DevicePresenter extends BasePresenterImpl<DeviceContract.IView> implements DeviceContract.IPresent {
    private Context mContext;
    private CommonModelImpl mModel;
    private Handler mHandler;
    private Runnable mRunnable;
    private List<DeviceInfoBean> mGatewayList;
    private ExecutorService mExecutorService;

    private boolean isFirstSyn = true;

    public DevicePresenter(Context mContext, Handler handler) {
        this.mContext = mContext;
        this.mHandler = handler;
        mModel = new CommonModel(mHandler);
        mExecutorService = Executors.newSingleThreadExecutor();
    }

    @Override
    public void getGatewayList() {
        mModel.onGetGatewayList(new onModelCallBack() {
            @Override
            public void onResponse(IoTResponse response) {
                if (response.getCode() == 200) {
                    mGatewayList = ParsingJsonUtil.getInstance().getGatewayList(response.getData());
                    handleGatewayData();
                }else {
                    mHandler.post(() -> mView.showMsg(response.getLocalizedMsg()));
                }
            }

            @Override
            public void onFailure(Exception e) {
                GatewayUdpUtil.getInstance().setDeviceInfoBeans(DeviceDaoUtil.getInstance().findAllGateway());
            }
        });
    }

    private void handleGatewayData(){
        Runnable runnable1 = ()-> updateGatewayList(mGatewayList);
        mExecutorService.execute(runnable1);
        getRoomListByAccount();
        Runnable runnable2 = ()-> startSynchronization(mGatewayList);
        mExecutorService.execute(runnable2);
    }

    @Override
    public void getRoomListByAccount() {
        Runnable runnable = () -> mModel.onQueryRoomList(1, 100, new onModelCallBack() {
            @Override
            public void onResponse(IoTResponse response) {
                if (response.getCode() == 200) {
                    List<VirtualUserBean> userList = ParsingJsonUtil.getInstance().getRoomAndCameraList(response.getData());
                    RoomDaoUtil.getInstance().getRoomData(mContext, userList);
                    mHandler.post(()->refreshDevice(1));
                }else {
                    mHandler.post(() -> mView.showMsg(response.getLocalizedMsg()));
                }
            }

            @Override
            public void onFailure(Exception e) {

            }
        });
        mExecutorService.execute(runnable);
    }

    @Override
    public void updateGatewayList(List<DeviceInfoBean> gatewayList) {
        if (gatewayList !=null && gatewayList.size()>0){
            List<String> deviceNameList = new ArrayList<>();
            for (DeviceInfoBean gateway : gatewayList) {
                DeviceDaoUtil.getInstance().updateGateway(gateway);
                String deviceName = gateway.getDeviceName();
                deviceNameList.add(deviceName);
                SceneDaoUtil.getInstance().synDefaultScene(mContext, deviceName);
            }
            DeviceDaoUtil.getInstance().synGatewayData(deviceNameList);
            GatewayUdpUtil.getInstance().setDeviceInfoBeans(gatewayList);
        }else {
            DeviceDaoUtil.getInstance().deleteAllDataExceptCamera();
        }
        mHandler.post(this::refreshViews);
    }

    @Override
    public void startSynchronization(List<DeviceInfoBean> gatewayList) {
        if (isFirstSyn){
            try {
                Thread.sleep(1500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            isFirstSyn = false;
        }
        if (gatewayList !=null && gatewayList.size()>0) {
            for (DeviceInfoBean gateway : gatewayList) {
                if (gateway.getStatus() == 1) { //网关在线 开始同步
                    synchronizationGateway(gateway);
                } else {//网关离线, 判断是否在内网
                    mHandler.post(()->refreshDevice(2));
                    stopGatewayIsOffLine(gateway.getDeviceName());
                }
            }
        }
    }

    @Override
    public void stopGatewayIsOffLine(String deviceName) {
        NetworkType networkType = NetWorkUtil.getInstance().getNetworkType(mContext);
        if (networkType == NetworkType.NETWORK_WIFI){
            mRunnable = () -> {
                if (!GatewayUdpUtil.getInstance().isGatewayIntranet(deviceName)){
                    DeviceDaoUtil.getInstance().updateDeviceOffLine(deviceName);
                }
            };
            mHandler.postDelayed(mRunnable, 6000);
        }else {
            DeviceDaoUtil.getInstance().updateDeviceOffLine(deviceName);
        }
    }

    @Override
    public void synchronizationGateway(DeviceInfoBean device) {
        SendDeviceCommand mSend = new SendDeviceCommand(mContext, device);
        mSend.queryOrSetGatewayInfo("00", "00");
    }

    @Override
    public void synchronizationSubDevice(String deviceName, String roomId) {
        DeviceInfoBean gateway = DeviceDaoUtil.getInstance().findGatewayByDeviceName(deviceName);
        if(gateway!=null){
            gateway.setRoom_id(Integer.parseInt(roomId, 16) > 9 ? "00" : roomId);
            DeviceDaoUtil.getInstance().getDeviceDao().update(gateway);
            String crc = CoderUtils.getDeviceCRC(gateway.getDeviceName());
            String timezone = CoderUtils.getTimeZone();
            SendDeviceCommand sendDeviceCommand = new SendDeviceCommand(mContext, gateway);
            sendDeviceCommand.synAllDeviceStatus(crc, timezone);
        }
    }

    @Override
    public void synchronizationNickName(String deviceName) {
        DeviceInfoBean gateway = DeviceDaoUtil.getInstance().findGatewayByDeviceName(deviceName);
        if(gateway!=null){
            String crc = CoderUtils.getDeviceNameCRC(deviceName);
            SendDeviceCommand sendDeviceCommand = new SendDeviceCommand(mContext, gateway);
            sendDeviceCommand.synGetDeviceName(crc);
        }
    }

    @Override
    public void synchronizationScene(String deviceName) {
        DeviceInfoBean gateway = DeviceDaoUtil.getInstance().findGatewayByDeviceName(deviceName);
        if (gateway != null) {
            SendSceneCommand mSend = new SendSceneCommand(mContext, gateway);
            String scene_crc = CoderUtils.getSceneCRC(deviceName);
            mSend.synScene(scene_crc);
        }
    }

    @Override
    public void synchronizationFinish(String deviceName) {
        refreshDevice(0);
        synchronizationScene(deviceName);
    }

    @Override
    public void refreshViews() {
        refreshDevice(0);
        LiveDataBus.get().with(CommonId.REFRESH_SCENE).setValue(0);
        LiveDataBus.get().with(CommonId.REFRESH_ALARM).setValue(1);
    }

    private void refreshDevice(int state){
        Log.i(TAG, "initDataBus: " + state);
        LiveDataBus.get().with(CommonId.REFRESH_DEVICE).setValue(state);
        List<DeviceInfoBean> mList = DeviceDaoUtil.getInstance().getDeviceDao().queryAll();
        mView.deviceListIsEmpty(mList.size()<=0);
    }

    @Override
    public void clickChildItem(DeviceInfoBean device) {
        SmartDevice mDevice = SmartDevice.getType(device.getDevice_type());
        Intent intent = new Intent();
        intent.putExtra(CommonId.KEY_DEVICE_NAME, device.getDeviceName());
        intent.putExtra(CommonId.KEY_DEVICE_ID, device.getDevice_ID());
        switch (mDevice){
            case EE_DEV_PIR:
            case EE_DEV_SOS:
            case EE_DEV_DOOR:
            case EE_DEV_BUTTON:
            case EE_DEV_CO_ALARM:
            case EE_DEV_SM_ALARM:
            case EE_DEV_WT_ALARM:
            case EE_DEV_GAS_ALARM:
            case EE_DEV_NEW_GAS_ALARM:
            case EE_DEV_CO_GAS_ALARM:
            case EE_DEV_MODE_BUTTON:
            case EE_DEV_SX_SM_ALARM:
            case EE_DEV_THERM_ALARM:
            case EE_DEV_FLASH_ALARM:
                intent.setClass(mContext, AlarmDeviceActivity.class);
                mView.skipActivity(intent);
                break;
            case EE_DEV_LOCK:
                intent.setClass(mContext, LockDetailActivity.class);
                mView.skipActivity(intent);
                break;
            case EE_DEV_SOCKET:
            case EE_DEV_MANIPULATOR:
            case EE_DEV_SOLENOID_VALVE:
                intent.setClass(mContext, SocketDetailActivity.class);
                mView.skipActivity(intent);
                break;
            case EE_DEV_TH_CHECK:
                intent.setClass(mContext, THCheckDetailActivity.class);
                mView.skipActivity(intent);
                break;
            case EE_TEMP_CONTROL:
                intent.setClass(mContext, TempControlDetailActivity.class);
                mView.skipActivity(intent);
                break;
            case EE_TEMP_OUTDOOR_SIREN:
                intent.setClass(mContext, OutDoorDetailActivity.class);
                mView.skipActivity(intent);
                break;
            case EE_SIMULATE_IPC:
                Intent intent1 = new Intent(mContext, CameraDeviceActivity.class);
                intent1.putExtra("FUN_DEVICE_ID", device.getDeviceName());
                intent1.putExtra("FUN_DEVICE_NAME", device.getSubdeviceName());
                mView.skipActivity(intent1);
                break;
        }
    }

    @Override
    public void viewOnDestroy() {
        if (mRunnable!=null) {
            mHandler.removeCallbacks(mRunnable);
        }
        mHandler.removeCallbacksAndMessages(null);
        if (mExecutorService!=null && !mExecutorService.isShutdown()){
            mExecutorService.isShutdown();
        }
    }
}
